﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace az
{
    class testy
    {
        public static Graph GenerateRandom(int n, int m)
        {
            if (n <= 0)
            {
                return null;
            }
            int[][] matrix = new int[n][];
            for (int i = 0; i < n; i++)
                matrix[i] = new int[n];


            ////////////////////////
            Graph temp = new Graph();
            Random random_gen = new Random();
            int v1, v2;
            int max;
            max = n * n - n;
            max = max >> 1;
            if (m > max)
                return null;
            while (m > 0)
            {
                v1 = random_gen.Next(n);
                v2 = random_gen.Next(n);
                if (matrix[v1][v2] == 1 || v1 == v2)
                    continue;
                else
                {
                    matrix[v1][v2] = matrix[v2][v1] = 1;
                    m--;
                }
            }

            ///////////////////////
            Vertex[] tempv = new Vertex[n];
            for (int i = 0; i < n; i++)
            {
                tempv[i] = new Vertex(i + 1, 0, 0);
                temp.listVertex.Add(tempv[i]);
            }
            temp.countVertex = n;
            int k = 0;
            for (int i = 0; i < n; i++)
            {
                int z = 0;
                for (int j = i+1; j < n; j++)
                {
                    
                    if (matrix[i][j] == 1)
                    {
                        Edge e = new Edge(k+1, tempv[i], tempv[j], 0);
                        temp.listEdge.Add(e);
                        tempv[i].listVertexNeighbor.Add(tempv[j]);
                        tempv[j].listVertexNeighbor.Add(tempv[i]);
                        tempv[i].listEdgeConnected.Add(e);
                        tempv[j].listEdgeConnected.Add(e);
                        k++;
                        z++;
                    }
                    
                }
                tempv[i].countVertexNeighbour = z;
            }
            temp.countEdge = k;
            return temp;
        }
        
        public static Graph GenerateRandom(int n, float p)
        {
            if (n <= 0)
            {
                return null;
            }
            int[][] matrix = new int[n][];
            for (int i = 0; i < n; i++)
                matrix[i] = new int[n];
            /////////
            Graph temp = new Graph();
            Random random_gen = new Random();
            double rand;
            int m = 0;
            for (int i = 0; i < n; i++)
            {
                for (int j = i + 1; j < n; j++)
                {
                    rand = random_gen.NextDouble();
                    if (rand < p)
                    {
                        matrix[i][j] = 1;
                        matrix[j][i] = 1;
                        m++;
                    }
                }
            }
            ////////////
            Vertex[] tempv = new Vertex[n];
            for (int i = 0; i < n; i++)
            {
                tempv[i] = new Vertex(i + 1, 0, 0);
                temp.listVertex.Add(tempv[i]);
            }
            temp.countVertex = n;
            int k = 0;
            for (int i = 0; i < n; i++)
            {
                int z = 0;
                for (int j = i + 1; j < n; j++)
                {
                   
                    if (matrix[i][j] == 1)
                    {
                        Edge e = new Edge(k+1, tempv[i], tempv[j], 1);
                        temp.listEdge.Add(e);
                        tempv[i].listVertexNeighbor.Add(tempv[j]);
                        tempv[j].listVertexNeighbor.Add(tempv[i]);
                        tempv[i].listEdgeConnected.Add(e);
                        tempv[j].listEdgeConnected.Add(e);
                        k++;
                        z++;
                    }
                }
                tempv[i].countVertexNeighbour = z;
            }
            temp.countEdge = k;
            return temp;
        }
        public static void PrintGraph(Graph g)
        {
            foreach (Vertex v in g.listVertex)
            {
                Console.Write("w" + v.number + ": ");
                foreach (Vertex x in v.listVertexNeighbor)
                {
                    Console.Write(x.number + " ");
                }
                Console.WriteLine(" ");
            }
        }
        public static void TestyAll(int from, int to, int increment, int try_count,double multi,bool isdense, bool LF, bool SL, bool DSatur)
        {
            int count = (to - from) / increment + 1;
            long[][] time = new long[3][];
            for (int i = 0; i < 3; i++)
                time[i] = new long[count];
            int k = 0;
            for (int i = from; i <= to; i = i + increment)
            {
                int m = (int)(i * multi);
                long sl = 0, lf = 0, ds = 0;
                if (isdense)
                    m = m * i;
                Graph[] g_tab = new Graph[try_count];
                for (int j = 0; j < try_count; j++)
                    g_tab[j] = testy.GenerateRandom(i, m);
                foreach (Graph g in g_tab)
                {
                    //testy.PrintGraph(g);
                    if (SL)
                        sl += testy.SL(g);
                    if (DSatur)
                        ds += testy.DSatur(g);
                    if (LF)
                        lf += testy.LF(g);
                    /*
                    foreach (Vertex v in g.listVertex)
                        Console.Write(v.numberColor + " ");
                    Console.WriteLine(" ");
                     * */
                }
                time[0][k] = Convert.ToInt64((float)sl / try_count);
                time[1][k] = Convert.ToInt64((float)lf / try_count);
                time[2][k] = Convert.ToInt64((float)ds / try_count);
                k++;
            }
            k = 0;
            for (int i = from; i <= to; i = i + increment)
            {
                float normed = 0;
                Console.WriteLine("Rozmiar: " + i);
                if (SL)
                {
                    normed = (float)time[0][k] / i;
                    if (isdense)
                        normed = normed / i;
                    Console.WriteLine("SL: " + time[0][k]+ " normed: " + normed);
                }
                if (LF)
                {
                    normed = (float)time[1][k] / i;
                    if (isdense)
                        normed = normed / i;
                    Console.WriteLine("LF: " + time[1][k] + " normed: " + normed);
                }
                if (DSatur)
                {
                    normed = (float)time[2][k] / (i*i);
                    if (isdense)
                        normed = normed / i;
                    Console.WriteLine("DSatur: " + time[2][k] + " normed: " + normed);
                }
                k++;
            }
        }
        public static long SL(Graph g, bool IsMax = false, int max = 0)
        {
            SmallestLast sl = new SmallestLast();
            Graph graphClone = Form1.CloneObject<Graph>(g);
            System.Diagnostics.Stopwatch s = new System.Diagnostics.Stopwatch();
            s.Start();
            sl.SmallestLastAlgoritm(g, graphClone, IsMax, max);
            s.Stop();
            return s.ElapsedTicks;
        }
        public static long LF(Graph g, bool IsMax = false, int max = 0)
        {
            LargestFirst lf = new LargestFirst();
            System.Diagnostics.Stopwatch s = new System.Diagnostics.Stopwatch();
            s.Start();
            lf.LargestFirstAlgoritm(g, IsMax, max);
            s.Stop();
            return s.ElapsedTicks;
        }
        public static long DSatur(Graph g, bool IsMax = false, int max = 0)
        {
            DSatur ds = new DSatur();
            System.Diagnostics.Stopwatch s = new System.Diagnostics.Stopwatch();
            s.Start();
            ds.DStaturAlgoritm(g, IsMax, max);
            s.Stop();
            return s.ElapsedTicks;
        }
        public static void GenerateCoords(Graph g,int middle,int radius)
        {
            int x, y;
            foreach (Vertex v in g.listVertex)
            {
                int i = v.number;
                x = (int)Math.Round(radius * Math.Cos(2 * Math.PI * i / g.countVertex) + middle);
                y = (int)Math.Round(-1 * radius * Math.Sin(2 * Math.PI * i / g.countVertex) + middle);
                v.point = new System.Drawing.Point(x, y);
            }
        }
    }
}
